/*
 * Copyright @ 苏州瑞云信息技术有限公司 All rights reserved.
 */
package cn.com.recloud.bbs.service.impl;

import cn.com.recloud.bbs.constant.BbsConstant;
import cn.com.recloud.bbs.constant.MetaOptionConstant;
import cn.com.recloud.bbs.dao.CampaignSignUpDao;
import cn.com.recloud.bbs.dao.OpenedLogDao;
import cn.com.recloud.bbs.dao.SharedLogDao;
import cn.com.recloud.bbs.dto.CampaignAnalysisDTO;
import cn.com.recloud.bbs.entity.*;
import cn.com.recloud.bbs.dao.CampaignDao;
import cn.com.recloud.bbs.service.CampaignService;
import cn.com.recloud.bbs.service.MetaoptionService;
import cn.com.recloud.bbs.service.NumberRuleService;
import cn.com.recloud.bbs.util.NumberUtil;
import cn.com.recloud.bbs.vo.AppLogoVO;
import cn.com.recloud.bbs.vo.CampaignAnalysisVO;
import cn.com.recloud.bbs.vo.CampaignAppVO;
import cn.com.recloud.bbs.vo.CampaignVO;
import cn.com.recloud.core.constant.SysConstant;
import cn.com.recloud.core.util.StringUtil;
import cn.com.recloud.one.spring.exception.OneException;
import cn.com.recloud.one.spring.service.CityService;
import cn.com.recloud.one.spring.service.impl.BaseServiceImpl;
import cn.com.recloud.one.spring.util.CacheUtil;
import cn.com.recloud.one.spring.util.ExportUtil;
import cn.com.recloud.one.spring.util.RequestUserUtils;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.commons.lang3.StringUtils;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author kim dong
 * @date 2020-06-08
 */
@Service
@CacheConfig(cacheNames = "bbs")
public class CampaignServiceImpl extends BaseServiceImpl<CampaignDao, bbs_campaign> implements CampaignService {
    @Autowired
    private MetaoptionService metaoptionService;
    @Autowired
    private CampaignDao campaignDao;
    @Autowired
    private OpenedLogDao openedLogDao;
    @Autowired
    private CityService cityService;
    @Autowired
    private CampaignSignUpDao signUpDao;
    @Autowired
    private SharedLogDao sharedLogDao;
    @Autowired
    private NumberRuleService numberRuleService;

    @Value("${url.backUrl}")
    private String backUrl;
    @Value("${url.appUrl}")
    private String frontUrl;
    @Value("${recloud.request-expire}")
    private Integer expireTime;

    /**
     * 新增活动并返回插入的id
     */
    @Override
    public String saveCampaign(bbs_campaign entity) {
        //查询选项集
        metaoption option = metaoptionService.findMetaOptionBySetNameAndValue(MetaOptionConstant.CAMPAIGN_STATUS, "1");
        entity.setBbs_campaign_statusname(option.getName());
        entity.setBbs_campaign_status(option.getValue());
        entity.setCode(getCampaignCode());

        campaignDao.insert(entity);
        return entity.getBbs_campaignid();
    }


    /**
     * 新增并发布活动并返回一个id
     */
    @Override
    public String releaseCampaign(String flag, bbs_campaign entity) {

        //新增活动
        if (StringUtils.isEmpty(entity.getBbs_campaignid())) {
            metaoption option = metaoptionService.findMetaOptionBySetNameAndValue(MetaOptionConstant.CAMPAIGN_STATUS, "1");
            entity.setBbs_campaign_statusname(option.getName());
            entity.setBbs_campaign_status(option.getValue());
            entity.setCode(getCampaignCode());
            campaignDao.insert(entity);
        }

        //判断启动页的图片是否是删除无状态
        if (!entity.getIs_display_start_page() && "1".equals(flag)) {
            // 此判断是防止在新建活动时，上传了启动图片又删除了图片，导致找不到这个活动的id，报空指针异常的情况
            if (StringUtils.isNotEmpty(entity.getBbs_campaignid()))
                // 删除启动页的图片
                campaignDao.deleteStartPage(entity.getBbs_campaignid());
        }

        //发布活动
        metaoption option = metaoptionService.findMetaOptionBySetNameAndValue(MetaOptionConstant.CAMPAIGN_STATUS, "2");
        entity.setBbs_campaign_status(option.getOptionid());
        entity.setBbs_campaign_status(option.getValue());
        entity.setBbs_campaign_statusname(option.getName());
        entity.setReleasedby(RequestUserUtils.getUserId());
        entity.setReleasedbyname(RequestUserUtils.getUserName());
        entity.setReleasedon(new Date());
        campaignDao.updateById(entity);
        return entity.getBbs_campaignid();


    }

    /**
     * 获取活动详情页的数据信息
     *
     * @param id
     * @return
     */
    @Override
    public CampaignVO getCampaignVO(String id) {
        CampaignVO vo = new CampaignVO();
        bbs_campaign campaign = campaignDao.selectById(id);
        if (ObjectUtil.isEmpty(campaign)) throw new OneException("你查询的详情不存在！");
        vo.setBbs_campaignid(id);
        vo.setCode(campaign.getCode());
        vo.setBbs_campaign_status(campaign.getBbs_campaign_status());
        vo.setBbs_campaign_statusname(campaign.getBbs_campaign_statusname());
        vo.setName(campaign.getName());
        vo.setStart_time(campaign.getStart_time());
        vo.setEnd_time(campaign.getEnd_time());
        vo.setAvatar(campaign.getAvatar());
        vo.setStart_page(campaign.getStart_page());
        vo.setIs_display_start_page(campaign.getIs_display_start_page());
        if (StringUtils.isNotEmpty(campaign.getProviceid())) {
            vo.setAddress(cityService.queryProvinceAndCityAndCounty(campaign.getProviceid(), campaign.getCityid(), campaign.getCountyid()) + campaign.getAddress());
        }
        vo.setSpeaker(campaign.getSpeaker());
        vo.setSpeaker_brief(campaign.getSpeaker_brief());
        vo.setBbs_campaign_link(campaign.getBbs_campaign_link());
        vo.setRemark(campaign.getRemark());
        vo.setCampaign_brief(campaign.getCampaign_brief());
        Integer count = openedLogDao.selectCount(new QueryWrapper<bbs_opened_log>().lambda().eq(bbs_opened_log::getObject_id, campaign.getBbs_campaignid())
                .eq(bbs_opened_log::getObject_type_name, MetaOptionConstant.CAMPAIGN_ENTITY_NAME));
        vo.setReadCount(count);
        return vo;
    }

    /**
     * 发布活动
     *
     * @param id
     * @return
     */
    @Override
    public boolean activateRelease(String id) {
        //获取选项集
        metaoption option = metaoptionService.findMetaOptionBySetNameAndValue(MetaOptionConstant.CAMPAIGN_STATUS, "2");
        bbs_campaign campaign = new bbs_campaign();
        campaign.setBbs_campaignid(id);
        campaign.setBbs_campaign_status(option.getValue());
        campaign.setBbs_campaign_statusname(option.getName());
        return campaignDao.updateById(campaign) >= 1;
    }

    /**
     * 取消发布活动
     *
     * @param id
     * @return
     */
    @Override
    public boolean deactivateRelease(String id) {
        metaoption option = metaoptionService.findMetaOptionBySetNameAndValue(MetaOptionConstant.CAMPAIGN_STATUS, "1");
        bbs_campaign campaign = new bbs_campaign();
        campaign.setBbs_campaignid(id);
        campaign.setBbs_campaign_status(option.getValue());
        campaign.setBbs_campaign_statusname(option.getName());
        return campaignDao.updateById(campaign) >= 1;
    }

    //格式化时间
    @Deprecated
    public String getFormatTime(Date start, Date end) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy.MM.dd kk.mm");
        String startTime = format.format(start);
        String endTime = format.format(end);
        return new StringBuffer(startTime).append(" - ").append(endTime).toString();
    }


    /**
     * 获取活动编号
     *
     * @return
     */
    @Override
    public String getCampaignCode() {
        number_rule numberrule = numberRuleService.getOne(new QueryWrapper<number_rule>().lambda().eq(number_rule::getPrefix, BbsConstant.CAMPAIGN_CODE).eq(number_rule::getStatecode, SysConstant.STATECODE_ENABLE));
        String code = NumberUtil.createNumber(numberrule.getPrefix(), numberrule.getCurentnumber());
        numberrule.setCurentnumber(code);
        numberrule.setName(code);
        numberRuleService.updateById(numberrule);
        return code;
    }

    /**
     * 活动的批量发布
     */
    @Override
    public boolean releaseBatch(List<String> idList, String type) {
        if (idList.size() == 0) return false;
        List list = new ArrayList<bbs_campaign>();
        metaoption option = metaoptionService.findMetaOptionBySetNameAndValue(MetaOptionConstant.CAMPAIGN_STATUS, type);
        for (String id : idList) {
            bbs_campaign campaign = new bbs_campaign();
            campaign.setBbs_campaignid(id);
            campaign.setBbs_campaign_status(option.getValue());
            campaign.setBbs_campaign_statusname(option.getName());
            list.add(campaign);
        }
        return super.updateBatchById(list);
    }

    /**
     * 活动分析数据的获取
     */
    @Override
    public Map listCampaignAnalysisTwo(CampaignAnalysisDTO campaign) {
        int index = (campaign.getPageIndex() - 1) * campaign.getPageSize();
        campaign.setPageIndex(index);
        Map map = new HashMap();
        List<CampaignAnalysisVO> analysis = campaignDao.listPageCampaignAnalysis(campaign);
        int count = campaignDao.listCountCampaignAnalysis(campaign);
        map.put("list", analysis);
        map.put("count", count);
        return map;
    }

    /**
     * 活动分析数据导出
     *
     * @param campaign
     * @param response
     */
    @Override
    public void exportCampaignAnalysis(CampaignAnalysisDTO campaign, HttpServletResponse response) {
        List<CampaignAnalysisVO> analysis = campaignDao.exportCampaignAnalysis(campaign);
        ExportUtil<CampaignAnalysisVO> exportUtil = new ExportUtil<>();
        exportUtil.export(response, analysis, campaign.getExportMap(), campaign.getExportName());
    }

    @Override
//    @Cacheable(key = "#code")
    public Map findAllShowCampaign(String time, String code) {
        HashMap<String, Object> map = new HashMap(4);
        /**
         * 判断前端传过来的时间和当前时间是否在过期时间内
         * 若没过期，不查表，直接返回空
         * 否则查询最新广告信息返回前端
         */
        List<AppLogoVO> mapList = new ArrayList<>();
        //第一次查询时间为空
        if (StringUtils.isBlank(time)) {
            mapList = this.findShowInStart();
            map.put("time", System.currentTimeMillis());
            //再次查询判断时间是否过期
        } else if ((System.currentTimeMillis() - Long.valueOf(time)) / (1000 * 60) > expireTime) {
            mapList = this.findShowInStart();
            map.put("time", System.currentTimeMillis());
        } else {
            map.put("time", time);
        }
        // 是否展示广告，1是0否
        if (mapList.size() > 0) {
            map.put("isShow", 1);
            map.put("isUpdate", 1);
        } else {
            map.put("isShow", 0);
            map.put("isUpdate", 0);
        }
        map.put("list", mapList);
        return map;
    }

    /**
     * 查询所有需要在启动页展示的活动
     * 提前三天展示
     */
    public List<AppLogoVO> findShowInStart() {
        List<AppLogoVO> mapList = new ArrayList<>();
        String imgPrefix = backUrl + "/image/detail/";
        String urlPrefix = frontUrl + "/#/campaign-detail?goFormStart=true&id=";
        Calendar calendar2 = Calendar.getInstance();
        SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd");
        calendar2.add(Calendar.DATE, 3);
        String threeDaysAfter = sdf2.format(calendar2.getTime());
        Date dateEnd = DateUtil.parse(threeDaysAfter + " 23:59:59");
        LambdaQueryWrapper<bbs_campaign> lambda = new QueryWrapper<bbs_campaign>().lambda();
        lambda.eq(bbs_campaign::getIs_display_start_page, true)
                .eq(bbs_campaign::getBbs_campaign_status, "2")
                .gt(bbs_campaign::getStart_time, new Date())
                .lt(bbs_campaign::getStart_time, dateEnd);
        List<bbs_campaign> list = campaignDao.selectList(lambda);
        list.forEach(item -> {
            if (StringUtil.isHttpStartUrl(item.getStart_page())) {
                mapList.add(new AppLogoVO(item.getBbs_campaignid(), item.getName(),
                        item.getStart_page(), urlPrefix + item.getBbs_campaignid()));
            } else {
                mapList.add(new AppLogoVO(item.getBbs_campaignid(), item.getName(),
                        imgPrefix + item.getStart_page(), urlPrefix + item.getBbs_campaignid()));
            }
        });
        return mapList;
    }


    @Override
    public List<CampaignAppVO> findAppCampaignList(String name, Integer pageIndex, Integer pageSize) {
        if (pageIndex <= 0) {
            return null;
        }
        Page<CampaignAppVO> page = new Page<>(pageIndex, pageSize);
        return campaignDao.selectAppCampaignPage(page, name);
    }

    /**
     * 更新文章时，如果启动页被删除则此方法单独删除图片和更新其他信息的操作
     *
     * @param campaign 更新的信息
     */
    @Override
    public void updateStById(bbs_campaign campaign) {
        campaignDao.updateStById(campaign);
    }

    @Override
    public boolean removeByIds(Collection<? extends Serializable> idList) {
        if(CollectionUtil.isEmpty(idList)) throw new OneException("请使用Id删除活动");
        List<bbs_campaign> campaigns = campaignDao.selectBatchIds(idList);
        List<String> ids= new ArrayList<>();
        for (bbs_campaign campaign :campaigns){
            if(campaign.getBbs_campaign_status().equals(MetaOptionConstant.RELEASE_STAUS_ABLE)){
                ids.add(campaign.getBbs_campaignid());
            }
        }
        if (CollectionUtil.isNotEmpty(ids)) throw new OneException("已发布的活动不能删除！");
        campaignDao.deleteBatchIds(idList);
        return true;
    }
}
